home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
comm
/
misc
/
xqsrc1_7.lzh
/
library
/
error.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-12
|
5KB
|
257 lines
/*
* Name: error.c
*
* Description: Error reporting functions for xferq.library
*
* Copyright: 1992-1993 by David Jones.
*
* Distribution:
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
*
* The Free Software Foundation David Jones
* 675 Mass Ave 6730 Tooney Drive
* Cambridge, MA Orleans, Ontario
* 02139 K1C 6R4
* USA Canada
*
* Usenet: gnu@prep.ai.mit.edu aa457@freenet.carleton.ca
* Fidonet: 1:163/109.8
*
* $Log: $
*
*/
#include <exec/types.h>
#include <exec/semaphores.h>
#include <proto/exec.h>
#include <proto/utility.h>
#include "xferq.h"
#include "xferqint.h"
#include "xferq_pragmas.h"
#include "execlists.h"
#define HT_SIZE 71
struct MinList ETable[HT_SIZE];
extern struct SignalSemaphore ObjectLock;
char *ErrorMsgs[] = {
"Operation successful",
"Insufficient memory",
"Disk I/O error",
"End of queue detected",
"Required tag missing",
"Object is locked",
"Object does not exist",
"Bad address specification",
"No session in progress",
"Illegal use of object",
"Work already queued"
};
void InitErrors(void)
/*
* Does: Initializes the ENode table upon opening the library.
*/
{
int i;
for (i = 0; i < HT_SIZE; i++) {
NEWLIST(&ETable[i]);
}
}
struct ENode *FindENode(BOOL create)
/*
* In: create TRUE to create ENode if not found.
*
* Does: Finds the ENode associated with the current process. If one
* cannot be found, it is created if requested.
*/
{
struct ENode *en;
struct Task *task;
int hash;
ObtainSemaphore(&ObjectLock);
task = FindTask(NULL);
hash = (ULONG)task % HT_SIZE;
en = FIRST(&ETable[hash]);
while (NEXT(en)) {
if (en->task == task) {
ReleaseSemaphore(&ObjectLock);
return en;
}
en = NEXT(en);
}
en = NULL;
if (create) {
/*
* We must use memobj's low level allocator since AllocObject
* calls Error() upon error, which calls FindENode...
*/
en = AllocObject(sizeof(struct ENode), XQO_ENODE);
if (en) {
en->task = task;
en->error = XQERROR_OK;
en->flags = 0;
ADDHEAD(&ETable[hash], en);
}
}
ReleaseSemaphore(&ObjectLock);
return en;
}
void DropENode(struct ENode *en)
/*
* In: en ENode to destroy.
*
* Does: Removes and returns the ENode to the system. This function
* helps keep the ENode table clean.
*/
{
ObtainSemaphore(&ObjectLock);
REMOVE(en);
FreeObject(en);
ReleaseSemaphore(&ObjectLock);
}
ULONG *PeekError(void)
/*
* Does: Returns a pointer to the address where error codes should be
* stored.
*/
{
struct ENode *en;
en = FindENode(TRUE);
if (en) {
return &en->error;
}
else {
return NULL;
}
}
void Error(long code)
/*
* In: code Error code to set
*
* Does: Installs the error code in the ENode.
*/
{
BOOL create;
struct ENode *en;
/*
* Prevent recursive loop if ENode can't be created due to lack
* of memory.
*/
create = (code == XQERROR_NOMEM) ? FALSE : TRUE;
en = FindENode(create);
if (en) {
en->error = code;
}
}
void SetErrorTags(struct TagItem *tags)
/*
* In: tags Taglist passed to a tag function
*
* Does: Searches for the tags XQ_ErrorCode and XQ_ErrorMsg and fills
* in the data if found.
*/
{
long code, *codeP;
char **msgP;
struct ENode *en;
/*
* Get the error code. If the ENode cannot be created, then treat
* the error as lack of memory.
*/
en = FindENode(TRUE);
if (en) {
code = en->error;
}
else {
code = XQERROR_NOMEM;
}
codeP = (long *)GetTagData(XQ_ErrorCode, NULL, tags);
msgP = (char **)GetTagData(XQ_ErrorMsg, NULL, tags);
/*
* Stuff the code and message pointers if they exist.
*/
if (codeP) {
*codeP = code;
}
if (msgP) {
*msgP = XfqErrorMsg(code);
}
/*
* Clear the error code only if any tags were asked for.
*/
if ((codeP || msgP) && en) {
en->error = XQERROR_OK;
}
}
LONG __saveds __asm LIBGetError(void)
/*
* Does: Returns the error code and clears it.
*/
{
struct ENode *en;
long code;
en = FindENode(TRUE);
if (en) {
code = en->error;
en->error = XQERROR_OK;
}
else {
code = XQERROR_NOMEM;
}
return code;
}
char *__saveds __asm LIBErrorMsg(register __d0 LONG error)
/*
* In: error D0 Error code returned by XfqGetError
*
* Does: Returns a pointer to an error message associated with the
* given error code.
*/
{
return CopyString(ErrorMsgs[error]);
}